package com.jeesite.modules.dao;

import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.entity.PaymentOrder;
import com.jeesite.modules.dto.PaymentOrderDto;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;
import java.util.Map;

/**
 * 支付订单DAO接口
 * @author LaVenderGong
 * @version 2025-08-16
 */
@MyBatisDao
public interface PaymentOrderDao extends CrudDao<PaymentOrder> {

    /**
     * 原生插入支付订单（避免StackOverflowError）
     */
    @Insert("INSERT INTO payment_orders (order_id, donation_id, payment_method, amount, status, create_time) " +
            "VALUES (#{orderId}, #{donationId}, #{paymentMethod}, #{amount}, #{status}, #{createTime})")
    int insertPaymentOrder(@Param("orderId") String orderId,
                          @Param("donationId") Long donationId,
                          @Param("paymentMethod") String paymentMethod,
                          @Param("amount") java.math.BigDecimal amount,
                          @Param("status") String status,
                          @Param("createTime") java.util.Date createTime);

    /**
     * 原生更新支付订单状态（避免StackOverflowError）
     */
    @Update("UPDATE payment_orders SET status = #{status}, pay_time = #{payTime}, " +
            "third_party_order_id = #{thirdPartyOrderId}, callback_data = #{callbackData} " +
            "WHERE order_id = #{orderId}")
    int updatePaymentOrderStatus(@Param("orderId") String orderId,
                                @Param("status") String status,
                                @Param("payTime") java.util.Date payTime,
                                @Param("thirdPartyOrderId") String thirdPartyOrderId,
                                @Param("callbackData") String callbackData);

    /**
     * 根据订单ID查询支付订单
     */
    @Select("SELECT * FROM payment_orders WHERE order_id = #{orderId}")
    PaymentOrder findByOrderId(@Param("orderId") String orderId);

    /**
     * 根据订单ID查询支付订单（原生查询，避免StackOverflowError）
     */
    @Select("SELECT order_id, donation_id, payment_method, amount, status, " +
            "third_party_order_id, create_time, pay_time, callback_data " +
            "FROM payment_orders WHERE order_id = #{orderId}")
    Map<String, Object> findByOrderIdNative(@Param("orderId") String orderId);

    /**
     * 根据订单ID查询支付订单（返回DTO，避免StackOverflowError）
     */
    @Select("SELECT order_id as orderId, donation_id as donationId, payment_method as paymentMethod, " +
            "amount, status, third_party_order_id as thirdPartyOrderId, " +
            "create_time as createTime, pay_time as payTime, callback_data as callbackData " +
            "FROM payment_orders WHERE order_id = #{orderId}")
    PaymentOrderDto findByOrderIdDto(@Param("orderId") String orderId);

    /**
     * 根据第三方订单号查询支付订单
     */
    @Select("SELECT * FROM payment_orders WHERE third_party_order_id = #{thirdPartyOrderId}")
    PaymentOrder findByThirdPartyOrderId(@Param("thirdPartyOrderId") String thirdPartyOrderId);

    /**
     * 根据捐赠记录ID查询支付订单
     */
    @Select("SELECT * FROM payment_orders WHERE donation_id = #{donationId}")
    List<PaymentOrder> findByDonationId(@Param("donationId") Long donationId);

    /**
     * 更新订单状态
     */
    @Update("UPDATE payment_orders SET " +
            "status = #{status}, " +
            "pay_time = #{payTime}, " +
            "third_party_order_id = #{thirdPartyOrderId}, " +
            "callback_data = #{callbackData} " +
            "WHERE order_id = #{orderId}")
    int updateOrderStatus(@Param("orderId") String orderId,
                         @Param("status") String status,
                         @Param("payTime") String payTime,
                         @Param("thirdPartyOrderId") String thirdPartyOrderId,
                         @Param("callbackData") String callbackData);

    /**
     * 获取超时未支付的订单
     */
    @Select("SELECT * FROM payment_orders " +
            "WHERE status IN ('CREATED', 'PAYING') " +
            "AND create_time < DATE_SUB(NOW(), INTERVAL #{timeoutMinutes} MINUTE)")
    List<PaymentOrder> findTimeoutOrders(@Param("timeoutMinutes") int timeoutMinutes);

    /**
     * 根据支付方式统计订单
     */
    @Select("SELECT payment_method, status, COUNT(*) as count " +
            "FROM payment_orders " +
            "GROUP BY payment_method, status")
    List<Map<String, Object>> getOrderStatistics();

    /**
     * 获取指定状态的订单数量
     */
    @Select("SELECT COUNT(*) FROM payment_orders WHERE status = #{status}")
    int countByStatus(@Param("status") String status);

    /**
     * 获取今日订单统计
     */
    @Select("SELECT " +
            "COUNT(*) as totalCount, " +
            "COUNT(CASE WHEN status = 'SUCCESS' THEN 1 END) as successCount, " +
            "COUNT(CASE WHEN status = 'FAILED' THEN 1 END) as failedCount, " +
            "SUM(CASE WHEN status = 'SUCCESS' THEN amount ELSE 0 END) as successAmount " +
            "FROM payment_orders " +
            "WHERE DATE(create_time) = CURDATE()")
    Map<String, Object> getTodayStatistics();

    /**
     * 批量更新超时订单状态
     */
    @Update("UPDATE payment_orders SET status = 'FAILED' " +
            "WHERE status IN ('CREATED', 'PAYING') " +
            "AND create_time < DATE_SUB(NOW(), INTERVAL #{timeoutMinutes} MINUTE)")
    int updateTimeoutOrders(@Param("timeoutMinutes") int timeoutMinutes);

    /**
     * 获取最近的订单记录
     */
    @Select("SELECT * FROM payment_orders " +
            "ORDER BY create_time DESC " +
            "LIMIT #{limit}")
    List<PaymentOrder> getRecentOrders(@Param("limit") int limit);
}
